package dsx.lockProxy;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import dsx.config.Config;

public class SimpleLock {

	private static String ownerKey = "";
	private static boolean ownerKeyReady = false;

	private static String getOwnerKey() throws Exception {
		if (!ownerKeyReady) {
			ownerKey = Config.get("Lock", "ownerKey");
			ownerKeyReady = true;
		}
		if (ownerKey == "")
			throw new Exception("锁配置异常");
		return ownerKey;
	}

	private static int rowTimeout = -1;
	private static boolean rowTimeoutReady = false;

	private static int getRowTimeout() throws Exception {
		if (!rowTimeoutReady) {
			rowTimeout = Integer.parseInt(Config.get("Lock", "rowTimeout"));
			rowTimeoutReady = true;
		}
		if (rowTimeout == -1)
			throw new Exception("锁配置异常");
		return rowTimeout;
	}

	private static int collectionTimeout = -1;
	private static boolean collectionTimeoutReady = false;

	private static int getCollectionTimeout() throws Exception {
		if (!collectionTimeoutReady) {
			collectionTimeout = Integer.parseInt(Config.get("Lock",
					"collectionTimeout"));
			collectionTimeoutReady = true;
		}
		if (collectionTimeout == -1)
			throw new Exception("锁配置异常");
		return collectionTimeout;
	}

	private static int rowWaitTimeout = -1;
	private static boolean rowWaitTimeoutReady = false;

	private static int getRowWaitTimeout() throws Exception {
		if (!rowWaitTimeoutReady) {
			rowWaitTimeout = Integer.parseInt(Config.get("Lock",
					"rowWaitTimeout"));
			rowWaitTimeoutReady = true;
		}
		if (rowWaitTimeout == -1)
			throw new Exception("锁配置异常");
		return rowWaitTimeout;
	}

	private static int collectionWaitTimeout = -1;
	private static boolean collectionWaitTimeoutReady = false;

	private static int getCollectionWaitTimeout() throws Exception {
		if (!collectionWaitTimeoutReady) {
			collectionWaitTimeout = Integer.parseInt(Config.get("Lock",
					"collectionWaitTimeout"));
			collectionWaitTimeoutReady = true;
		}
		if (collectionWaitTimeout == -1)
			throw new Exception("锁配置异常");
		return collectionWaitTimeout;
	}

	private static Map<String, Object> lockMap = new HashMap<String, Object>();
	private static Random random = new Random();

	private static String getRandKey() {
		synchronized (lockMap) {
			String s = "";
			do {
				int i = Math.abs(random.nextInt());
				s = Integer.toString(i);
			} while (lockMap.containsKey(s));
			lockMap.put(s, null);
			return s;
		}
	}

	private static void freeRandKey(String s) {
		synchronized (lockMap) {
			if (lockMap.containsKey(s))
				lockMap.remove(s);
		}
	}

	// 单集合单行锁
	public static Object lockRow(String collectionKey, String rowKey)
			throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockRow(collectionKey, rowKey, ownerKeyRand, getRowTimeout(),
				getRowWaitTimeout())) {
			return new _Lock(2, collectionKey, rowKey, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockRow(String collectionKey, String rowKey,
			int lockTimeout, int waitTimeout) throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockRow(collectionKey, rowKey, ownerKeyRand, lockTimeout,
				waitTimeout)) {
			return new _Lock(2, collectionKey, rowKey, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	// 单集合多行锁
	public static Object lockRows(String collectionKey, List<String> rowKeys)
			throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockRows(collectionKey, rowKeys, ownerKeyRand,
				getRowTimeout(), getRowWaitTimeout())) {
			return new _Lock(3, collectionKey, rowKeys, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockRows(String collectionKey, List<String> rowKeys,
			int lockTimeout, int waitTimeout) throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockRows(collectionKey, rowKeys, ownerKeyRand, lockTimeout,
				waitTimeout)) {
			return new _Lock(3, collectionKey, rowKeys, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	// 多集合多行锁
	public static Object lockRows(List<String> collectionKeys,
			List<String> rowKeys) throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockRows(collectionKeys, rowKeys, ownerKeyRand,
				getRowTimeout(), getRowWaitTimeout())) {
			return new _Lock(4, collectionKeys, rowKeys, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockRows(List<String> collectionKeys,
			List<String> rowKeys, int lockTimeout, int waitTimeout)
			throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockRows(collectionKeys, rowKeys, ownerKeyRand, lockTimeout,
				waitTimeout)) {
			return new _Lock(4, collectionKeys, rowKeys, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockCollection(String collectionKey) throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockCollection(collectionKey, ownerKeyRand,
				getCollectionTimeout(), getCollectionWaitTimeout())) {
			Thread.sleep(getRowTimeout());
			return new _Lock(0, collectionKey, null, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockCollection(String collectionKey, int lockTimeout,
			int waitTimeout) throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockCollection(collectionKey, ownerKeyRand, lockTimeout,
				waitTimeout)) {
			Thread.sleep(getRowTimeout());
			return new _Lock(0, collectionKey, null, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockCollections(List<String> collectionKeys)
			throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockCollections(collectionKeys, ownerKeyRand,
				getCollectionTimeout(), getCollectionWaitTimeout())) {
			Thread.sleep(getRowTimeout());
			return new _Lock(1, collectionKeys, null, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	public static Object lockCollections(List<String> collectionKeys,
			int lockTimeout, int waitTimeout) throws Exception {
		String randKey = getRandKey();
		String ownerKeyRand = getOwnerKey() + randKey;
		if (Lock.lockCollections(collectionKeys, ownerKeyRand, lockTimeout,
				waitTimeout)) {
			Thread.sleep(getRowTimeout());
			return new _Lock(1, collectionKeys, null, randKey);
		} else {
			freeRandKey(randKey);
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public static void releaseLock(Object lockObject) {
		try {
			_Lock lock = (_Lock) lockObject;
			if (lock == null)
				return;
			String ownerKeyRand = getOwnerKey() + lock.randKey;
			switch (lock.lockType) {
			case 0:
				Lock.releaseCollection((String) lock.collectionKey,
						ownerKeyRand);
				break;
			case 1:
				Lock.releaseCollections((List<String>) lock.collectionKey,
						ownerKeyRand);
				break;
			case 2:
				Lock.releaseRow((String) lock.collectionKey,
						(String) lock.rowKey, ownerKeyRand);
				break;
			case 3:
				Lock.releaseRows((String) lock.collectionKey,
						(List<String>) lock.rowKey, ownerKeyRand);
				break;
			case 4:
				Lock.releaseRows((List<String>) lock.collectionKey,
						(List<String>) lock.rowKey, ownerKeyRand);
				break;
			}
			freeRandKey(lock.randKey);
		} catch (Exception ex) {
			// 记日志
		}
	}

}
